package com.utooo.service.system.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.utooo.dao.system.CategoryMapper;
import com.utooo.pojo.domain.system.CategoryDO;
import com.utooo.pojo.dto.system.inparam.CategoryCodeDto;
import com.utooo.pojo.dto.system.inparam.CategoryCodeLevelDto;
import com.utooo.pojo.dto.system.outparam.CategoryLevelOut;
import com.utooo.service.system.CategoryService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, CategoryDO> implements CategoryService {
    @Override
    public CategoryDO getCategory(CategoryCodeDto param) {
        // 获取父级分类编码
        String parentCode = param.getParentCode();
        CategoryDO parentCategory = null;
        String level = "1";
        // 如果父级分类编码不为"0"，则查询父级分类信息
        if (!"0".equals(parentCode)) {
            parentCategory = this.getOne(new LambdaQueryWrapper<CategoryDO>().eq(CategoryDO::getCode, param.getParentCode()));
        }
        // 生成自增编码
        String selfCode;
        // 如果父级分类不存在或父级分类的自增编码为空，则自增编码初始化为"1"
        selfCode = "1";
        if (parentCategory != null && parentCategory.getLevel()!= null && !parentCategory.getLevel().isEmpty()) {
            level = String.valueOf(Integer.parseInt(parentCategory.getLevel()) + 1);
        }
        // self是取最大值+1
        String maxSelfCode = "0";
        CategoryDO maxCategory = this.getBaseMapper().selectOne(new LambdaQueryWrapper<CategoryDO>()
                .eq(CategoryDO::getParentCode, param.getParentCode())
                .orderByDesc(CategoryDO::getSelfCode)
                .last("LIMIT 1"));

        if (maxCategory != null && maxCategory.getSelfCode() != null) {
            maxSelfCode = maxCategory.getSelfCode();
        }
        selfCode = String.valueOf(Integer.parseInt(maxSelfCode) + 1);

        // 生成完整分类编码
        String code;
        // 如果父级分类编码为"0"，则分类编码等于自增编码
        if ("0".equals(parentCode)) {
            code = selfCode;
        } else {
            // 否则，分类编码为父级分类编码加上格式化后的自增编码
            code = parentCategory.getCode() + String.format("%02d", Integer.parseInt(selfCode));
        }

        // 创建并设置分类对象
        CategoryDO categoryDO = new CategoryDO();
        categoryDO.setSelfCode(selfCode);
        categoryDO.setCode(code);
        categoryDO.setLevel(level);
        return categoryDO;
    }

    @Override
    public List<CategoryLevelOut> getCategoryLevelList(CategoryCodeLevelDto param) {
        // 获取层级以上的所有数据 包括最小的层级
        List<CategoryDO> categoryDOList = this.list(new LambdaQueryWrapper<CategoryDO>()
                .le(CategoryDO::getLevel, param.getLevel()));

        // 将CategoryDO列表转换为CategoryLevelOut列表
        List<CategoryLevelOut> categoryLevelOutList = categoryDOList.stream()
                .map(categoryDO -> {
                    CategoryLevelOut categoryLevelOut = new CategoryLevelOut();
                    categoryLevelOut.setCode(categoryDO.getCode());
                    categoryLevelOut.setName(categoryDO.getName());
                    categoryLevelOut.setLevel(categoryDO.getLevel());
                    categoryLevelOut.setParentCode(categoryDO.getParentCode());
                    return categoryLevelOut;
                })
                .collect(Collectors.toList());

        // 构建层级树
        return buildCategoryTree(categoryLevelOutList, "0");
    }

    /**
     * 递归构建分类层级树
     *
     * @param categoryList 分类列表
     * @param parentCode   父级编码
     * @return 分类层级树
     */
    private List<CategoryLevelOut> buildCategoryTree(List<CategoryLevelOut> categoryList, String parentCode) {
        List<CategoryLevelOut> tree = new ArrayList<>();
        for (CategoryLevelOut category : categoryList) {
            if (parentCode.equals(category.getParentCode())) {
                category.setChildCategory(buildCategoryTree(categoryList, category.getCode()));
                tree.add(category);
            }
        }
        return tree;
    }
}